A Brief Discussion on the Differences Between Git Merge and Rebase
I am writing this because a colleague recently shared with me that Markdown syntax supports Mermaid, which can be used to draw flowcharts. Since Git branch diagrams are relatively simple, I decided to refer to the documentation "Gitgraph Diagrams" to write this note and experiment with it.
Two Ways to Merge Branches
In Git, there are two common ways to merge branches: git merge and git rebase.
git merge: Merges changes from one branch into another while preserving the history of both branches. This creates a new merge commit, which clearly records when the two branches were merged.- Pros:
- Preserves the complete history, including the timestamp of each merge.
- When merging between heterogeneous branches, it is clearer to see how each change was integrated.
- You only need to resolve conflicts against the latest commit of the target branch. Therefore, you only need to resolve conflicts at most once.
- Cons:
- Frequent merging can make the history complex and difficult to read.
- Each merge creates a new merge commit, which may clutter the commit history with unnecessary commits.
- Pros:
git rebase: Moves the commits of one branch to the tip of another. This rewrites the history, making it look as if the commits started directly from the target branch.- Pros:
- Cleans up the commit history, making it look more concise and linear.
- Cons:
- Rewriting history may result in the loss of merge point records, making it difficult to track when a merge occurred.
- In a collaborative environment, it may cause confusion in the commit history and lead to difficult-to-resolve conflicts. However, you generally should not use
git rebaseon shared branches. - As each commit from the current branch is moved to the base branch, each commit is checked for conflicts. Therefore, you may need to resolve conflicts multiple times during a
git rebaseprocess.
- Pros:
Branch Diagram Examples
Below are the branch diagrams generated after git merge and git rebase operations.
Original branch history:
Result of Merge:
Result of Rebase:
When to Use Which
When using git merge and git rebase, a common criterion is the homogeneity or heterogeneity of the branches.
Homogeneous branches:
Homogeneous branches refer to two branches that share the same goal, usually the same branch in remote and local versions, such as
origin/mainandmain. In this case, usinggit rebaseis more appropriate.Heterogeneous branches:
Heterogeneous branches refer to two branches with different goals, such as
mainanddevelop. In this case,git mergeis usually the preferred choice.Some might find it strange, as synchronization between remote and local branches is usually done via
git pullandgit push, which seems unrelated togit merge. However,git pullessentially executes agit fetchto synchronize remote commits to a temporary local branch, followed by agit mergeto integrate those changes into the local branch.git pullcan be used with the--rebaseparameter, such asgit pull --rebase. This replacesgit mergewithgit rebaseafter synchronizing remote changes, integrating local changes on top of the remote changes.
Another scenario suitable for git rebase is when a team requires that branches must not have conflicts before submitting an MR (Merge Request, as called in GitLab, or Pull Request in GitHub). In this case, the person submitting the MR can use git rebase to move the current branch's commits to the latest state of the target branch, resolve all conflicts, and then submit the MR.
TIP
The responsibility for resolving conflicts—whether it lies with the reviewer or the MR submitter—varies by team. Please follow your team's guidelines.
Additionally, there is an advanced usage of git rebase called git rebase -interactive {start commit}, which can be used to squash, reorder, or edit commit messages. However, this is beyond the scope of this article and will not be detailed here.
WARNING
Except for git pull --rebase, Rebase-related operations should only be performed on your own development branches; do not perform them on shared branches.
Rebase operations on shared branches should only be performed before a git push. Once you have performed a git push and then change the local repository's commit history, it will cause the local and remote histories to diverge. If you use git push --force to forcibly update the remote repository, it will cause inconsistencies for everyone else's local repositories. Such operations not only affect team collaboration but can also lead to disputes.
Change Log
- 2024-08-23 Initial version created.
